import minimist from "minimist";
import path from "path";
import fs from "fs";
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export const screenshotFolderPath = path.join(__dirname, '../screenshot');
export const xhsBaseUrl = 'https://www.xiaohongshu.com';

export interface AppConfig {
    userAccount: string;
    larkAppID: string;
    larkAppSecret: string;
    larkAppToken: string;
    bitableTop20MonitorTableID: string;
    bitableSousuoGuanjianciTableID: string;
    bitableSousuoJieguoLiebiaoTableID: string;    
    bitableSousuoJieguoTableID: string;
    bitableSousuoJieguoBijiTableID: string;
    bitableSousuoJieguoBijiViewID: string;
    bitableSousuoJieguoGuandianTableID: string;
    bitableSousuoJieguoBrandTableID:string;

    bitableJiankongBijiTableID: string;
    bitableJiankongBijiXinxiTableID: string;
    bitableJiankongGuandianXinxiTableID: string;

    bitableGuandianshengchengTableID: string;

    retreiveNoteCount: number;

    openaiAPIKey: string;
    llmModel: string;

    geminiAPIKey: string;
    geminiModel: string;
  }

export interface Note {
  recordId?: string;
  id?: number;
  noteId?: string;
  url?: string;
  liveable?: boolean;
  title?: string;
  authorId?: string;
  author?: string;
  content?: string;
  publishDate?: number;
  likeCount?: number;
  collectCount?: number;
  chatCount?: number;
  screenshotPath?: string;
  screenshotFileToken?: string;
  comments?: Comment[];
}

export interface Comment {
  noteInfoId?: number;
  author?: string;
  authorId?: string;
  content?: string;
  publishDate?: number;
  likeCount?: number;
  replyCount?: number;
}

export class Queue<T> {
  private items: T[] = [];
  add(item: T) { this.items.push(item); }
  remove(): T | undefined { return this.items.shift(); }
  isEmpty(): boolean { return this.items.length === 0; }
}

export function parseLikeNumber(text: string): number {
    if (text.endsWith('万')) {
      return parseFloat(text.slice(0, -1)) * 10000;
    }
    return parseInt(text) || 0;
}

export function parseNoteId(url: string): string {
  return url?.split('/').pop()?.split('?')[0] || ''; //pattern: /search_results/1234567890?xxxx
}
  
export async function randomWait(min: number, max: number, showCountdown: boolean = true): Promise<void> {
  return new Promise((resolve) => {
    const endTime = Date.now() + Math.floor(Math.random() * (max - min + 1)) + min;
    
    const updateCountdown = () => {
      const remainingMs = endTime - Date.now();
      
      if (remainingMs <= 0) {
        resolve();
        if (showCountdown) {
          console.log('\r-------- Waiting done --------');
        }
        return;
      }
      
      const minutes = Math.floor(remainingMs / 60000);
      const seconds = Math.floor((remainingMs % 60000) / 1000);
      if (showCountdown) {
        process.stdout.write(`\rWaiting in: ${minutes}m ${seconds}s    `);
      }
      
      setTimeout(updateCountdown, 1000);
    };
    
    updateCountdown();
  });
}

//Parse date string as the format as:
// "3天前"
// "3小时前"
// "2025-04-26" or "编辑于 2025-04-26"
// "4-26" or "编辑于 4-26"
// "编辑于 4天前"
// "4-26 河南"
// "昨天"
// return the timestamp
export function parsePublishDate(dateString: string): number {
  ////remove the "编辑于" and trim leading and trailing spaces
  dateString = dateString.replace(/^.*?编辑于/, '').trim()
  //remove location " xx"
  dateString = dateString.split(' ')[0];

  let year = 0;
  let month = 0;
  let day = 0;
  if (dateString.includes('天前')) {
    // 例如：1天前
    const daysBefore = parseInt(dateString.split('天前')[0].trim());
    const now = new Date();
    year = now.getFullYear();
    month = now.getMonth();
    day = now.getDate() - daysBefore;
  } else if (dateString.includes('小时前') || dateString.includes('分钟前')) {
    // 例如：3小时前
    const now = new Date();
    year = now.getFullYear();
    month = now.getMonth();
    day = now.getDate();
  } else if (dateString.includes('昨天')) {
    // 例如：昨天
    const now = new Date();
    year = now.getFullYear();
    month = now.getMonth();
    day = now.getDate() - 1;
  } else {
    const dateArray = dateString.split(' ').slice(-1)[0].split('-');
    if (dateArray.length === 3) {
      // 例如：2025-04-26
      year = parseInt(dateArray[0]);
      month = parseInt(dateArray[1]) - 1;
      day = parseInt(dateArray[2]);
    }else {
      // 例如：4-26
      year = new Date().getFullYear();
      month = parseInt(dateArray[0]) - 1;
      day = parseInt(dateArray[1]);
    }
  }

  return new Date(year, month, day).getTime();
}

export function getProfile(): AppConfig {
    const args = minimist(process.argv.slice(2));

    const appProfile = args.profile || args.p || 'test'; 
    if (!appProfile) {
        throw new Error('Profile parameters not found. Please provide -p or --profile followed by a profile name');
    }

    const profilePath = path.join(__dirname, '../profile/app', appProfile + '.json');
    if (!fs.existsSync(profilePath)) {
        throw new Error('Profile file not found.');
    }    

    const appProfileJson = JSON.parse(fs.readFileSync(profilePath, 'utf8'));

    const userAccount = args.account || args.a || '19901749012';
    if (!userAccount) {
        throw new Error('Account parameters not found. Please provide -a or --account followed by account number');
    }

    const retreiveNoteCount = args.retreiveNoteCount || args.r || 300;

    return {
        userAccount: userAccount,
        larkAppID: appProfileJson.LARK_APP_ID,
        larkAppSecret: appProfileJson.LARK_APP_SECRET,
        larkAppToken: appProfileJson.LARK_APP_TOKEN,
        bitableTop20MonitorTableID: appProfileJson.BITABLE_TOP20MONITOR_TABLE_ID,
        bitableSousuoGuanjianciTableID: appProfileJson.BITABLE_SOUSUOGUANJIANCI_TABLE_ID,
        bitableSousuoJieguoLiebiaoTableID: appProfileJson.BITABLE_SOUSUOJIEGUOLIEBIAO_TABLE_ID,
        
        bitableSousuoJieguoTableID: appProfileJson.BITABLE_SOUSUOJIEGUO_TABLE_ID,
        bitableSousuoJieguoBijiTableID: appProfileJson.BITABLE_SOUSUOJIEGUOBIJI_TABLE_ID,
        bitableSousuoJieguoBijiViewID: appProfileJson.BITABLE_SOUSUOJIEGUOBIJI_VIEW_ID,
        bitableSousuoJieguoGuandianTableID: appProfileJson.BITABLE_SOUSUOJIEGUOGUANDIAN_TABLE_ID,
        bitableSousuoJieguoBrandTableID:appProfileJson.BITABLE_SOUSUOJIEGUOBrand_TABLE_ID,
        bitableJiankongBijiTableID: appProfileJson.BITABLE_JIANKONGBIJI_TABLE_ID,
        bitableJiankongBijiXinxiTableID: appProfileJson.BITABLE_JIANKONGBIJIXINXI_TABLE_ID,
        bitableJiankongGuandianXinxiTableID: appProfileJson.BITABLE_JIANKONGGUANDIANXINXI_TABLE_ID,
        bitableGuandianshengchengTableID: appProfileJson.BITABLE_GUANDIANSHENGCHENG_TABLE_ID,
        retreiveNoteCount: retreiveNoteCount,

        openaiAPIKey: appProfileJson.OPENAI_API_KEY,
        llmModel: appProfileJson.LLM_MODEL,
        
        geminiAPIKey: appProfileJson.GEMINI_API_KEY,
        geminiModel: appProfileJson.GEMINI_MODEL,        
    };
}

